package com.superzhou.dragview;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author zhoubo
 * @date 2020/8/13
 * @describe
 */
public class DragViewGroup extends ViewGroup {

    //行数
    private int rowNum = 3;
    //列数
    private int columnNum = 4;
    //间距
    private int spacingValue = 10;
    //子view宽度
    private int childWidth;
    //子view高度
    private int childHeight;
    //数据载体
    private int[]  markArray ;

    private int mySpecValue;

    //背景画笔
    private Paint paint;
    private int bgColor = 0xffE8E7E3;
    //背景格子
    private RectF rectF;

    Map<Integer, DragItemView> cancelViews = new HashMap<>();

    private List<DataBean> dataBeans = new ArrayList<>();

    private LayoutInflater inflater;

    private DragChangeListener mListener;
    //是否开启底部

    private boolean OpenBottom = true;
    //底部高度

    private int bottomHeight = 100;

    private int bottomButtonWidth = 0;
    private int bottomButtonHeight = 0;
    private int height;
    private int width;
    private int tempHeight;

    public void setListener(DragChangeListener mListener) {
        this.mListener = mListener;
    }

    public void setDataBeans(List<DataBean> dataBeans) {
        this.dataBeans = dataBeans;
        removeAllViews();
        if (bottomButton!=null)addView(bottomButton);
        for (int i = 0; i < dataBeans.size(); i++) {
            DragItemView mView = (DragItemView) inflater.inflate(R.layout.child_item, this, false);
            mView.setData(dataBeans.get(i));
            addView(mView);
            mView.init(dataBeans.get(i).getSourceName(),mListener);
            mView.StartAnim();
        }
    }

    public void addItem(DataBean databean){
        DragItemView mView = (DragItemView) inflater.inflate(R.layout.child_item, this, false);
        mView.setData(databean);
        addView(mView);
        mView.init(databean.getSourceName(),mListener);
        mView.StartAnim();
    }

    private Rect rect;

    public int getChildWidth() {
        return childWidth;
    }

    public int getChildHeight() {
        return childHeight;
    }

    private TextView bottomButton;

    public void addBottomButton(TextView view){
        this.bottomButton = view;
        addView(bottomButton);
    }

    public DragViewGroup(Context context) {
        this(context,null);
    }

    public DragViewGroup(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public DragViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = MeasureSpec.getSize(widthMeasureSpec);
        tempHeight =  height = (width /columnNum)*rowNum;
        mySpecValue = dp2px(getContext(),spacingValue);
        childWidth = (width -(columnNum-1)* mySpecValue)/columnNum;
        childHeight = (height -(rowNum-1)* mySpecValue)/rowNum;
        height += dp2px(getContext(),bottomHeight);
        bottomButtonWidth = dp2px(getContext(),150);
        bottomButtonHeight = dp2px(getContext(),40);
        for (int i = 0; i < getChildCount() ; i++) {
            if (getChildAt(i) instanceof DragItemView){
                getChildAt(i).measure(MeasureSpec.makeMeasureSpec(childWidth,MeasureSpec.EXACTLY),MeasureSpec.makeMeasureSpec(childHeight,MeasureSpec.EXACTLY));
            }
            else if (getChildAt(i) instanceof TextView)
                getChildAt(i).measure(MeasureSpec.makeMeasureSpec(bottomButtonWidth,MeasureSpec.EXACTLY),MeasureSpec.makeMeasureSpec(bottomButtonHeight,MeasureSpec.EXACTLY));
        }
        setMeasuredDimension(width, height);
    }
    private void init(){
        /*
         * 画笔样式分三种：
         * 1.Paint.Style.STROKE：描边
         * 2.Paint.Style.FILL_AND_STROKE：描边并填充
         * 3.Paint.Style.FILL：填充
         */
        inflater = ((Activity)getContext()).getLayoutInflater();
        markArray = new int[rowNum*columnNum];
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.FILL);
        paint.setStrokeWidth(5);
        paint.setColor(bgColor);
    }
    Rect buttonRect = new Rect();
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        //子view数量
        cancelViews.clear();
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            if (getChildAt(i) instanceof DragItemView){
                DragItemView childAt = (DragItemView) getChildAt(i);
                DataBean tempBean = childAt.getData();
                if (tempBean == null){
                    throw new SecurityException("This view data is Null");
                }
                cancelViews.put(tempBean.getIndex(),childAt);
                //控件所属行
                int row = tempBean.getIndex()/columnNum;
                //控件所在列
                int col = (tempBean.getIndex()+1)%columnNum==0?columnNum-1:((tempBean.getIndex()+1)%columnNum)-1;
                int left = col*childWidth+col*mySpecValue;
                int right = left+childWidth;
                int top = row*childHeight + row*mySpecValue;
                int bottom = top + childHeight;
                childAt.layout(left,top,right,bottom);
            }else if (getChildAt(i) instanceof TextView){
                TextView childAt = (TextView) getChildAt(i);
               int tempHeiht = tempHeight+((height-tempHeight-bottomButtonHeight)/2);
               int tempWidth = (width-bottomButtonWidth)/2;
               childAt.layout(tempWidth,tempHeiht,tempWidth+bottomButtonWidth,tempHeiht+bottomButtonHeight);
                buttonRect.set(tempWidth,tempHeiht,tempWidth+bottomButtonWidth,tempHeiht+bottomButtonHeight);
            }

        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        int  index = TouchIndex(ev.getX(),ev.getY());
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                break;
            case MotionEvent.ACTION_CANCEL:
                break;
        }
        return super.dispatchTouchEvent(ev);
    }
    int choseIndex = 0;
    int lastX = 0;
    int lastY = 0;
    int spaceX = 0;
    int spaceY = 0;
    int tempIndex = 0;
    DragItemView touchView = null;
    //是否在回收按钮㘝
    boolean isRecycle = false;
    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int tempX = 0;
        int tempY = 0;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
               tempIndex = choseIndex = TouchIndex(event.getX(),event.getY());
               if (choseIndex <= 0)return true;
                lastX = (int) event.getX();
                lastY = (int) event.getY();
                touchView = cancelViews.get(choseIndex-1);
                if (touchView== null) return true;
                touchView.bringToFront();
                spaceX = (int) (lastX -touchView.getX());
                spaceY = (int) (lastY - touchView.getY());
                if(bottomButton!=null)bottomButton.setText("拖入回收");
                break;
            case MotionEvent.ACTION_MOVE:
                if (touchView == null)return true;
                  tempX = (int) event.getX();
                  tempY = (int) event.getY();
                  int index = TouchIndex(touchView.getX()+spaceX/2,touchView.getY()+spaceY/2);
                  if (index >0)tempIndex = index;
                  else tempIndex = choseIndex;
                  isRecycle = EnterRecyclingButton(tempX,tempY);
                 touchView.layout(tempX-spaceX,tempY-spaceY,tempX-spaceX+touchView.getWidth(),tempY-spaceY+touchView.getHeight());
                break;
            case MotionEvent.ACTION_UP:
                if (touchView == null)return true;
                if (cancelViews.containsKey(tempIndex-1)){
                    DragItemView view = cancelViews.get(tempIndex - 1);
                   //view.setTag(choseIndex-1);
                    assert view != null;
                    replaceOrUpgrade(view,touchView);
                }else{
                    DataBean tag = (DataBean) touchView.getData();
                    tag.setIndex(tempIndex-1);
                    touchView.setData(tag);
                }
                if (isRecycle)
                RemoveView(touchView);
                if(bottomButton!=null)bottomButton.setText("快速购买");
                requestLayout();
                tempIndex = 0;
                touchView = null;

                //rect = TouchRect(touchView.getX()+spaceX,touchView.getY()+spaceY);
                //touchView.layout(rect.left, rect.top, rect.right, rect.bottom);
                break;
            case MotionEvent.ACTION_CANCEL:
                Log.e("TAG","ACTION_CANCEL");
                if (touchView == null)return true;
                DataBean tag = touchView.getData();
                tag.setIndex(tempIndex-1);
                touchView.setData(tag);
                requestLayout();
                tempIndex = 0;
                touchView = null;
                //Rect rect = TouchRect(touchView.getX()+spaceX/2,touchView.getY()+spaceY/2);
                //touchView.layout(rect.left, rect.top, rect.right, rect.bottom);
                return true;
        }
                return true;
    }

    private void CreateUpgradeView(DataBean bean){
        int oldLv = bean.getLv();
        bean.setLv(++oldLv);
        bean.setSourceName("lv"+oldLv);
        DragItemView mView = (DragItemView) inflater.inflate(R.layout.child_item, this, false);
        mView.setData(bean);
        addView(mView);
        mView.init(bean.getSourceName(),mListener);
        mView.StartAnim();
    }
    private void RemoveView(DragItemView view){
        view.StopAnim();
        this.removeView(view);
    }
    //替换或者升级
    public void  replaceOrUpgrade(DragItemView oldView,DragItemView moveView){
        DataBean tag = oldView.getData();
        DataBean tag2 =moveView.getData();
        if(tag.getLv() == tag2.getLv()&&tag.getIndex()!=tag2.getIndex()){//等级一样 升级
            oldView.StopAnim();
            moveView.StopAnim();
             removeView(oldView);
             removeView(moveView);
             CreateUpgradeView(tag);
        }else{//等级不一样 交换位置
            int tempIndex = tag.getIndex();
            int tempIndex2 = tag2.getIndex();
            tag.setIndex(tempIndex2);
            tag2.setIndex(tempIndex);
            oldView.setData(tag);
            moveView.setData(tag2);
        }


    }

    private boolean EnterRecyclingButton(float x ,float y){
        return (x>buttonRect.left&&x<buttonRect.right&&y>buttonRect.top&&y<buttonRect.bottom);
    }
    /**
     * 判断点击index
     * @param x x坐标
     * @param y y坐标
     * @return
     */
    private int TouchIndex(float x, float y){
       int row = 0;
       int col = 0;
        for (int i = 0; i < columnNum; i++) {
            if (x> i*childWidth+i*spacingValue&&x<(i*childWidth+i*spacingValue)+childWidth){
                col = i+1;
                break;
            }
        }
        for (int i = 0; i < rowNum; i++) {
            if (y> i*childHeight+i*spacingValue&&y<(i*childHeight+i*spacingValue)+childHeight){
                row = i+1;
                break;
            }
        }
         if (row == 0||col == 0)row=col=0;
        return ((row-1)*columnNum)+col;

    }
    private Rect TouchRect(float x, float y){
         int left = 0;
         int top = 0;
         int right = 0;
         int bottom = 0;
        for (int i = 0; i < columnNum; i++) {
            if (x> i*childWidth+i*spacingValue&&x<(i*childWidth+i*spacingValue)+childWidth){
                left = i*childWidth+i*spacingValue;
                right = left+childWidth;
                break;
            }
        }
        for (int i = 0; i < rowNum; i++) {
            if (y> i*childHeight+i*spacingValue&&y<(i*childHeight+i*spacingValue)+childHeight){
                top = i*childHeight+i*spacingValue;
                bottom = top +childHeight;
                break;
            }
        }

        return new Rect(left,top,right,bottom);

    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        DrawBackground(canvas);
        super.dispatchDraw(canvas);
    }

    /**
     * 是否可以添加item
     * @return
     */
    public boolean canBePurchased(){
        boolean flag = false;
        int num = getChildCount();
        if (bottomButton!=null)num -= 1;
        if (num<(columnNum*rowNum))flag = true;
        return flag;
    }

    /**
     * 最近可以摆放item index 返回-1 表示未找到坑位
     * @return
     */
    public int getFirstPlacement(){
        int firstPlacement = -1;
        for (int i = 0; i < columnNum *rowNum; i++) {
            if (!cancelViews.containsKey(i)){
                firstPlacement = i;
                break;
            }
        }
        return firstPlacement;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        rectF = new RectF();
    }
    private void DrawBackground(Canvas canvas){
        for (int i = 0; i < columnNum*rowNum; i++) {
            //控件所属行
            int row = i/columnNum;
            //控件所在列
            int col = (i+1)%columnNum==0?columnNum-1:((i+1)%columnNum)-1;
            int left = col*childWidth+col*mySpecValue;
            int top =  row*childHeight + row*mySpecValue;
            rectF.set(left,top,left+childWidth,top+childHeight);
            canvas.drawRoundRect(rectF, 50, 50, paint);
        }
    }

    private int dp2px(Context context, int dpValue) {
        if (context == null) {
            return 0;
        }
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        float density = displayMetrics != null ? displayMetrics.density : 0;
        return (int) (dpValue * density + 0.5f);
    }
}
